export default function createHashHistory() {
  let routerStack = [];
  let index = -1;
  let action = "POP";
  let listeners = [];
  let state;

  const go = (n) => {
    action = "POP";
    index += n; //更改栈顶的指针
    if (index >= 0 && index < routerStack.length) {
      const nextLocation = routerStack[index]; // 取出指定索引对应的路径对象
      state = nextLocation.state; // 取出此 location 对应的状态
      window.location.hash = nextLocation.pathname; // 修改hash值 ，从而修改当前的路径
    }
  };

  const goBack = () => {
    go(-1);
  };

  const goForward = () => {
    go(1);
  };

  const push = (pathname, nextState) => {
    action = "PUSH";
    if (typeof pathname === "object") {
      state = pathname.state;
      pathname = pathname.pathname;
    } else {
      state = nextState;
    }
    window.location.hash = pathname;
  };

  const listen = (listener) => {
    listeners.push(listener);
    return () => {
      listeners = listeners.filter((item) => item !== listener);
    };
  };

  const hashChangeHandler = () => {
    const pathname = window.location.hash.slice(1); // 取出最新的hash值对应的路径 #/xxx
    Object.assign(history, { action, location: { pathname, state } });

    if (action === "PUSH") {
      // 调用了 push 方法，需要往历史栈中添加新的条目
      routerStack[++index] = history.location;
    }

    listeners.forEach((listener) => listener({ location: history.location }));
  };
  window.addEventListener("hashchange", hashChangeHandler);

  const history = {
    action: "POP",
    location: {
      pathname: window.location.hash ? window.location.hash.slice(1) : "/",
      state: undefined,
    },
    go,
    goBack,
    goForward,
    push,
    listen,
  };
  if (window.location.hash) {
    // 如果初始的情况下，如果 hash 是有值的
    action = "PUSH";
    hashChangeHandler();
  } else {
    window.location.hash = "/";
  }
  // 在 window 上挂载自己的 myHistory, 这样就可以在控制台使用
  window.myHistory = history;
  return history;
}
